﻿using System.Collections.Generic;
using System.Linq;
using StockholmsStad.Data.Entity;
using StockholmsStad.Runtime.Serialization.DataContract;
using Ceremony=StockholmsStad.Runtime.Serialization.DataContract.Ceremony;
using Minister=StockholmsStad.Runtime.Serialization.DataContract.Minister;

namespace StockholmsStad.Data.ContractFactory
{
    /// <summary>
    /// Konvertering befintligt dataobjekt till kontraktsobjekt
    /// </summary>
    internal class CeremonyFactory
    {
        public Ceremony CreateContractObject(Entity.Ceremony ceremonyEntity, 
            IEnumerable<CeremonySpecialNeed> specialNeedEntities, 
            GetCeremonyLanguageResult ceremonyLanguagEntity, 
            GetCertificateLanguageResult certificateLanguageEntity, 
            Language requestedLanguage)
        {
            var contractCeremony = new Ceremony
                                       {
                                           CeremonyLanguage = new ValueIdPair
                                                                  {
                                                                      Name = ceremonyLanguagEntity.Name,
                                                                      Id = ceremonyLanguagEntity.CeremonyLanguageId
                                                                  },
                                           CertificateLanguage = new ValueIdPair
                                                                     {
                                                                         Name = certificateLanguageEntity.Name,
                                                                         Id = certificateLanguageEntity.CertificateLanguageId
                                                                     },
                                           ImpedimentDocIssuedDate = ceremonyEntity.ImpedimentDocIssuedDate,
                                           Interpreter = ceremonyEntity.Interpreter.HasValue
                                                             ? ceremonyEntity.Interpreter.GetValueOrDefault()
                                                             : false,
                                           ImpedimentDocAllowDelayDays = ceremonyEntity.ImpedimentDocAllowDelayDays,
                                           Note = ceremonyEntity.Note,
                                           OtherLanguage =
                                               requestedLanguage != null ? requestedLanguage.Name : string.Empty,
                                       };

            if (specialNeedEntities != null && specialNeedEntities.Count() != 0)
            {
                var needs = specialNeedEntities.Select(sp => sp.SpecialNeed);
                foreach (var need in needs)
                {
                    if(contractCeremony.SpecialNeeds == null)
                        contractCeremony.SpecialNeeds = new List<ValueIdPair>();

                    contractCeremony.SpecialNeeds.Add(new ValueIdPair { Id = need.SpecialNeedId, Name = need.Name });
                }
            }

            return contractCeremony;
        }

        public Entity.Ceremony CreateEntityObject(int ceremonyId, Ceremony ceremony, int impedimentDocAllowDelayDays,
            int ceremonyLanguageId, int certificateLanguageId)
        {
            var entityCeremony = new Entity.Ceremony
                                     {
                                         CeremonyId = ceremonyId,
                                         CeremonyLanguageId = ceremonyLanguageId,
                                         CertificateLanguageId = certificateLanguageId,
                                         Interpreter = ceremony.Interpreter,
                                         ImpedimentDocAllowDelayDays = impedimentDocAllowDelayDays,
                                         Note = ceremony.Note
                                     };

            if (ceremony.ImpedimentDocIssuedDate.HasValue)
                entityCeremony.ImpedimentDocIssuedDate = ceremony.ImpedimentDocIssuedDate.Value;

            return entityCeremony;
        }

        public IEnumerable<CeremonySpecialNeed> CreateEntitySpecialNeeds(int ceremonyId, IEnumerable<int> specialNeedIds)
        {
            IEnumerable<CeremonySpecialNeed> specialNeeds =
                specialNeedIds.Select(id => new CeremonySpecialNeed
                                                {
                                                    CeremonyId = ceremonyId,
                                                    SpecialNeedId = id
                                                });

            return specialNeeds;
        }

        public Language CreateEntityLanguage(string language)
        {
            return new Language {Name = language};
        }

        public CeremonyLanguage CreateEntityCeremonyLanguage(int id)
        {
            return new CeremonyLanguage {LanguageId = id};
        }

        public CertificateLanguage CreateEntityCertificateLanguage(int id)
        {
            return new CertificateLanguage {LanguageId = id};
        }

        public CeremonySpecialNeed CreateEntitySpecialNeed(int id)
        {
            return new CeremonySpecialNeed {SpecialNeedId = id};
        }

        public SpecialNeed CreateEntitySpecialNeed(string name)
        {
            return new SpecialNeed {Name = name};
        }

        public Language CreateEntityLanguage(ValueIdPair language)
        {
            return new Language { LanguageId = language.Id, Name = language.Name };
        }

        public ValueIdPair CreateContractObject(Language language)
        {
            return new ValueIdPair {Id = language.LanguageId, Name = language.Name};
        }

        public CeremonySummary CreateContractObject(GetIndividualCeremonyBookingForDateResult result)
        {
            var booking = new CeremonySummary
                              {
                                  Date = result.Date,
                                  Minister = new Minister
                                                 {
                                                     FirstNames = result.FirstNames,
                                                     LastName = result.LastName,
                                                     MinisterId = result.MinisterId
                                                 },
                              };
            return booking;
        }

        public CeremonySummary CreateContractObject(GetOrdinaryCeremonyBookingForDateResult result)
        {
            var booking = new CeremonySummary
            {
                Date = result.StartDate.Value,
                Minister = new Minister
                {
                    MinisterId = result.MinisterId,
                    FirstNames = result.MinisterFirstName,
                    LastName = result.MinisterLastName,
                },
                AvailableTimeBlocks = result.AvailableBlocks,
                BookedTimeBlocks = result.BookedBlocks,
                Queue = result.Queue,
            };

            if(result.TempMinisterId.HasValue)
            {
                booking.TempMinister = new Minister
                {
                    MinisterId = result.TempMinisterId,
                    FirstNames = result.TempMinisterFirstName,
                    LastName = result.TempMinisterLastName,
                };
            }

            return booking;
        }
    }
}